// Package zdb sql操作对象
package utils

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

// SQLConnecting 数据库连接对象
type SQLConnecting struct {
	UserName  string
	Password  string
	IPAddrees string
	Port      int
	DbName    string
	Charset   string
}

// SQLClient sql 操作客户端
type SQLClient struct {
	DBO *sqlx.DB
}

// CreatSQLClient 创建一个sql的客户端
func CreatSQLClient(sqlType string, sqlc SQLConnecting) (*SQLClient, error) {
	// 拼接连接字符串
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", sqlc.UserName, sqlc.Password, sqlc.IPAddrees, sqlc.Port, sqlc.DbName, sqlc.Charset)
	// sqlx.open 创建数据库类型
	Db, err := sqlx.Open(sqlType, dsn)
	if err != nil {
		return nil, err
	} else {
		return &SQLClient{Db}, nil
	}
	/* 	Db.SetMaxIdleConns(utils.GlobalObject.Sqlsetmaxidleconns)
	   	Db.SetMaxOpenConns(utils.GlobalObject.SetMaxOpenConns)
	   	Db.SetConnMaxLifetime(utils.GlobalObject.SetConnMaxLifetime) */
}

// NoQuery 执行非查询sql语句
// 同时支持存储过程，例如："call testcunchuguocheng('param1', 'param2')"
func (sqlc *SQLClient) NoQuery(sqls string) (int64, error) {
	result, err := sqlc.DBO.Exec(sqls)
	if err != nil {
		return 0, err
	}
	// RowsAffected 获取受影响的行数
	num, _ := result.RowsAffected()
	return num, nil
}

// QueryStruct 查询内容放入结构体中
// dest时根据查询结构封装的结构体，传入一个指针变量比如：var userData *userInfo = new(userInfo) sqlc.QueryStruct(userData, "select *from userinfo")
func (sqlc *SQLClient) QueryStruct(dest interface{}, sqls string) error {
	err := sqlc.DBO.Get(dest, sqls)
	if err != nil {
		return err
	}
	return nil
}

// QueryStructS 查询内容放入一个结构切片里
// dest 传入某个结构体的切片，例如： var userInfoSlice []userInfo  sqlc.QueryStructS(&userInfoSlice, "select * from userinfo")
func (sqlc *SQLClient) QueryStructS(dest interface{}, sqls string) error {
	err := sqlc.DBO.Select(dest, sqls)
	if err != nil {
		return err
	}
	return nil
}
